import Utils (tok, at, endsWith, readInt)
import Data.Char (isDigit)

type GameID = Int
type RGB    = (Int, Int, Int)
type Game   = (GameID, RGB)

-- Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
parseLine :: String -> Game
parseLine line =
    (gameID, findMax (0, 0, 0) rgbTokens)
    where
        tokens    = tok ":,;" line
        gameID    = readInt . reverse . takeWhile isDigit . reverse . at 0 $ tokens
        rgbTokens = map (drop 1) $ drop 1 tokens

        findMax (r, g, b) [] = (r, g, b)
        findMax (r, g, b) (s:ss) 
            | (endsWith "red" s) = findMax (max r val, g, b) ss
            | (endsWith "green" s) = findMax (r, max g val, b) ss
            | (endsWith "blue" s) = findMax (r, g, max b val) ss
            where
                val = readInt . takeWhile isDigit $ s

filterGameThr :: RGB -> [Game] -> [Game]
filterGameThr (rmax, gmax, bmax) games =
    filter allBelow games
    where
        allBelow = \(_, (r, g, b)) -> r <= rmax && g < gmax && b < bmax

power :: Game -> Int
power (_, (r, g, b)) = r * g * b

main = do
    contents <- readFile "input.txt"
    let games = map parseLine . lines $ contents
    print $ sum . map fst . filterGameThr (12, 13, 14) $ games
    print $ sum . map power $ games
